﻿using Storage.DbEntities.Base;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Storage.Repositories.Base
{
	public abstract class BaseRep<TDbEntity> : Storage.Repositories.Base.IRep where TDbEntity : BaseDbEntity, new()
	{
		protected SQLite.SQLiteAsyncConnection _connection;
		public BaseRep(SQLite.SQLiteAsyncConnection connection)
		{
			_connection = connection;
		}

        public String TableName
        {
            get
            {
                return typeof(TDbEntity).Name;
            }
        }

		public async Task Remove(TDbEntity dbEntity)
		{
			await _connection.DeleteAsync(dbEntity);
		}

		public async Task RemoveAll(IEnumerable<TDbEntity> dbEntities)
		{
			await _connection.DeleteAllAsync(dbEntities);
		}

		public Type TableType { get { return typeof(TDbEntity); } }

		public virtual async Task UpdateAsync(TDbEntity dbEntity)
		{
			await _connection.UpdateAsync(dbEntity);
		}

		public virtual async Task SaveAsync(TDbEntity dbEntity)
		{
			if (dbEntity.Id == Guid.Empty)
			{
				dbEntity.Id = Guid.NewGuid();
				await _connection.InsertAsync(dbEntity);
			}
			else
			{
				await _connection.UpdateAsync(dbEntity);
			}
		}

		public virtual async Task<Boolean> Exists(Guid id)
		{
			var res = await GetByIdAsync(id);
			return res != null;
		}

		public virtual async Task InsertAsync(TDbEntity dbEntity)
		{
			dbEntity.Id = Guid.NewGuid();
			await _connection.InsertAsync(dbEntity);
		}

		public virtual async Task<TDbEntity> GetByIdAsync(Guid id)
		{
			if (id == Guid.Empty)
				return null;

            var res = await _connection.FindAsync<TDbEntity>(id);
			return res;
		}

		public virtual async Task<List<TDbEntity>> GetAll()
		{
            return await Table().ToListAsync();
		}

        protected SQLite.AsyncTableQuery<TDbEntity> Table()
        {
            return _connection.Table<TDbEntity>();
        }

        public async Task DeleteById(Guid id)
        {
            var sqlDeleteCommand = String.Format("Delete From {0} where Id = ?", typeof(TDbEntity).Name);
            await _connection.ExecuteAsync(sqlDeleteCommand, id);
        }

		public async Task Clear()
		{
            var sqlDeleteCommand = String.Format("Delete From {0}", typeof(TDbEntity).Name);
            await _connection.ExecuteAsync(sqlDeleteCommand);
		}
	}
}
